package com.ag.oa.util;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


public class DateUtils {

    private static final Logger logger = LoggerFactory.getLogger(DateUtils.class);

    /**
     * 获取当前时间秒级别 (10位)
     * @return
     */
    public static long getCurrentTimeSeconds() {
        return (System.currentTimeMillis() / 1000);
    }

    /**
     * 取得指定日期所在周的第一天
     * @param date
     * @return
     */
    public static String getFirstDayOfWeek(Date date) {
        Calendar cal = new GregorianCalendar();
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek()); // Monday
        return format(cal.getTime(),"yyyy-MM-dd");
    }

    /**
     * 取得指定日期所在周的最后一天
     * @param date
     * @return
     */
    public static String getLastDayOfWeek(Date date) {
        Calendar cal = new GregorianCalendar();
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek() + 6); // Sunday
        return format(cal.getTime(),"yyyy-MM-dd");
    }

    /**
     * 是否这个月最后一天
     * @param date
     * @return
     */
    public static boolean isLastDayOfMonth(Date date){
        Calendar cDay1 = Calendar.getInstance();
        cDay1.setTime(date);
        int lastDay = cDay1.getActualMaximum(Calendar.DAY_OF_MONTH);
        int curDay = cDay1.get(Calendar.DAY_OF_MONTH);
        return lastDay == curDay;
    }

    /**
     * 获取第几年的第几周，根据日期
     *
     * mysql一致
     * SELECT YEARWEEK('2009-12-27','1'); -- 200952
     * SELECT YEARWEEK('2010-01-03','1'); -- 200953
     * SELECT YEARWEEK('2010-01-04','1'); -- 201001
     * SELECT YEARWEEK('2019-12-29','1'); -- 201952
     * SELECT YEARWEEK('2019-12-30','1'); -- 202001
     * SELECT YEARWEEK('2020-01-06','1'); -- 202002
     *
     * oracle的IW周算法一致
     *
     * @param date
     * @return key(week、year)
     */
    public static Map<String,Integer> getYearAndWeekOfDate(Date date){
        Map<String,Integer> yearAndWeekMap = new HashMap<>();

        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY); // 星期一是，一周的开始
        cal.setMinimalDaysInFirstWeek(4); // 设置一年中第一个星期所需的最少天数 with 4 or more days this year
        cal.setTime(date);

        int week = cal.get(Calendar.WEEK_OF_YEAR);
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH)+1;
        // 年头 并且 大于50周，说明是属于去年的，所以年减1
        if(month == 1 && week>50){
            year--;
        }
        // 年尾 并且 是第1周，说明是下一年的，所以年加1
        if(month == 12 && week==1){
            year++;
        }
        yearAndWeekMap.put("week",week);
        yearAndWeekMap.put("year",year);
        return yearAndWeekMap;
    }

    /**
     * 获取季度
     * @param date
     * @return
     */
    public static int getQuarter(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int month = cal.get(Calendar.MONTH) + 1;

        if (month >= 1 && month <= 3) {
            return 1;
        } else if (month >= 4 && month <= 6) {
            return 2;
        } else if (month >= 7 && month <= 9) {
            return 3;
        } else {
            return 4;
        }
    }

    /**
     * 根据日期取得星期几
     * @param date
     * @return
     */
    public static String getWeek(Date date){
        String[] weeks = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"}; // 0~6
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if(week_index<0){
            week_index = 0;
        }
        return weeks[week_index];
    }

    /**
     * 获得时间范围的所有日期
     * @author wjc
     * @param startDateStr 开始日期字符串yyyy-MM-dd
     * @param endDateStr 结束日期字符串yyyy-MM-dd
     * @param pattern 返回日期的格式
     * @return 区间的所有日期
     */
    public static List<String> getBetweenDays(String startDateStr, String endDateStr, String pattern) {
        // 返回的日期集合
        List<String> days = new ArrayList<>();

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat getDateFormat = new SimpleDateFormat(pattern);
        try {
            Date startDate = dateFormat.parse(startDateStr);
            Date endDate = dateFormat.parse(endDateStr);

            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(startDate);

            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(endDate);
            tempEnd.add(Calendar.DATE, +1);// 包含结束时间

            while (tempStart.before(tempEnd)) {
                days.add(getDateFormat.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }
        } catch (ParseException e) {
            logger.error(e.getMessage(),e);
        }
        return days;
    }

    /**
     * 日期格式化
     * @param date 需要格式化的日期
     * @param pattern 格式
     */
    public static String format(Date date, String pattern) {

        String datePattern = "";
        if (date == null || StringUtils.isBlank(pattern)) {
            return datePattern;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        datePattern = sdf.format(date);

        return datePattern;
    }

    /**
     * 字符串转日期
     * @param stringDate 字符串日期
     */
    public static Date stringToDate(String stringDate, String pattern) {
        if (StringUtils.isBlank(stringDate)) {
            return null;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date = null;
        try {
            date = sdf.parse(stringDate);
        } catch (ParseException e) {
            logger.error(e.getMessage());
        }
        return date;
    }

    /**
     * 获取指定时间，之前或之后几天的日期
     * @author wjc
     * @param date 日期
     * @param amount 整数(1表示加1天， -1表示减一天)
     * @return 日期字符 yyyy-MM-dd
     */
    public static String getBeforeOrAfterDay(Date date, int amount){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE,amount);
        Date time = calendar.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time);
    }
    public static String getBeforeOrAfterDay(String date, int amount){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(stringToDate(date,"yyyy-MM-dd"));
        calendar.add(Calendar.DATE,amount);
        Date time = calendar.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time);
    }

}
